home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / uemacs-3.000 / uemacs-3 / uemacs-3.8 / main.c,v < prev    next >
Encoding:
Text File  |  1995-09-22  |  40.7 KB  |  1,248 lines

  1. head    1.1;
  2. access;
  3. symbols;
  4. locks
  5.     moss:1.1; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.1
  10. date    95.09.22.23.31.08;    author moss;    state Exp;
  11. branches;
  12. next    ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19. 1.1
  20. log
  21. @Initial revision
  22. @
  23. text
  24. @/*
  25.  *    MicroEMACS 3.8
  26.  *             written by Dave G. Conroy.
  27.  *            greatly modified by Daniel M. Lawrence
  28.  *
  29.  *    (C)opyright 1987 by Daniel M. Lawrence
  30.  *    MicroEMACS 3.8 can be copied and distributed freely for any
  31.  *    non-commercial purposes. MicroEMACS 3.8 can only be incorporated
  32.  *    into commercial software with the permission of the current author.
  33.  *
  34.  * This file contains the main driving routine, and some keyboard processing
  35.  * code, for the MicroEMACS screen editor.
  36.  *
  37.  * REVISION HISTORY:
  38.  *
  39.  * 1.0  Steve Wilhite, 30-Nov-85
  40.  *      - Removed the old LK201 and VT100 logic. Added code to support the
  41.  *        DEC Rainbow keyboard (which is a LK201 layout) using the the Level
  42.  *        1 Console In ROM INT. See "rainbow.h" for the function key defs
  43.  *      Steve Wilhite, 1-Dec-85
  44.  *      - massive cleanup on code in display.c and search.c
  45.  *
  46.  * 2.0  George Jones, 12-Dec-85
  47.  *      - Ported to Amiga.
  48.  *
  49.  * 3.0  Daniel Lawrence, 29-Dec-85
  50.  *      - rebound keys/added new fast buffered I/O for AMIGA
  51.  *    - added META- repeat commands
  52.  *    - added reposition default to center screen (yeah!)
  53.  *    - changed exit with modified buffers message
  54.  *    - made filesave tell us what it is doing
  55.  *    - changed search string entry to terminate with <ESC>
  56.  *      so we can use <NL> in search/replace strings
  57.  *    - updated version number in mode line to 3.0
  58.  *    12-Jan-86
  59.  *    - Added code to reconize the Search/replace functions
  60.  *    - Added code to perform search/replace & query functions
  61.  *    14-Jan-86
  62.  *    - moved search logic to separate function in search.c
  63.  *    - added replace and query replace functions
  64.  *    - separated out control key expansions to be used by others in search.c
  65.  *    15-Jan-86
  66.  *    - changed "visiting" to finding
  67.  *    - changed yes/no responces to not need return
  68.  *    - cleaned up various messages
  69.  *    16-jan-86
  70.  *    - fixed spurious spawn message in MSDOS
  71.  *    - added ^X-S synonime to save command
  72.  *    - moved escape to shell to ^X-C
  73.  *    21-jan-86
  74.  *    - added code to suspend shell under BSD
  75.  *    22-jan-86
  76.  *    - added function key support (SPEC) under MSDOS
  77.  *    - Abort now prints [Aborted] on message line
  78.  *    23-jan-86
  79.  *    - Added modes and commends to set/unset them
  80.  *    24-jan-86
  81.  *    - Added Goto Line command
  82.  *    - added Rename Buffer command
  83.  *    28-jan-86
  84.  *    - added goto beginning and end of paragraph commands (META-P/META-N)
  85.  *    - re-wrote kdelete to use realloc. gained MUCH speed here when
  86.  *      doing large wipes both on UNIX and MSDOS. Changed kill buffer
  87.  *      allocation block size from 256 bytes to 1 k
  88.  *    29-jan-86
  89.  *    - moved extern function declarations to efunc.h
  90.  *    - made name[] name binding table
  91.  *    30-jan-86
  92.  *    - fixed Previous/Next paragraph command not to wrap around EOF
  93.  *    - added Fill Paragraph command (META-Q)
  94.  *    4-feb-86
  95.  *    - added code to properly display long lines, scrolling them right
  96.  *      to left
  97.  *    5-feb-85
  98.  *    - rewrote code to right/left scroll...much better
  99.  *    - added shifted arror keys on IBMPC
  100.  *    6-feb-85
  101.  *    - add option to allow forword-word to jump to beginning of
  102.  *      next word instead of end of current one. This is different from
  103.  *      other emacs' but can be configured off in estruct.h
  104.  *    - added VIEW mode to allow a buffer to be read only
  105.  *       (-v switch on command line will activate this)
  106.  *    - changed quick exit to write out ALL changed buffers!!!
  107.  *      MAKE SURE YOU KNOW THIS WHEN META-Zing
  108.  *    10-feb-86
  109.  *    - added handling of lines longer than allowed on file read in
  110.  *      (they wrap on additional lines)
  111.  *    - made having space clear the message line and NOT insert itself
  112.  *      a configuration option in ed.h
  113.  *    11-feb-86
  114.  *    - added Describe-command and Help commands.
  115.  *    13-feb-86
  116.  *    - added View file command (^X ^V) and finished HELP command
  117.  *    14-feb-86
  118.  *    - added option to let main loop skip update if type ahead commands
  119.  *       are queued up
  120.  *    16-feb-86
  121.  *    - added Insert File command
  122.  *    17-feb-86
  123.  *    - added scroll next window up/down commands
  124.  *    18-feb-86
  125.  *    - added CMODE indentation
  126.  *    - re-arranged header files to standerdize extern and global
  127.  *      definitions
  128.  *    - changed version number to 3.2
  129.  *    - added numeric arguments to search, reverse search and
  130.  *      search and replace
  131.  *    24-feb-86
  132.  *    - added Bind To Key function (^C for now) to allow the user
  133.  *      to change his command keys
  134.  *    - added Unbind key function (M-^C for now)
  135.  *    - added execute named command to execute unbound commands (M-X)
  136.  *    - added describe bindings command (not bound)
  137.  *    - changed version number to 3.3
  138.  *    25-feb-86
  139.  *    - scrapped CERROR mode (too many compilers)
  140.  *    - added EXACT mode for case sensitive searchers
  141.  *    26-feb-86
  142.  *    - added command completion on execute named command and
  143.  *      all routined grabbing a command name
  144.  *    - adding execute-command-line command and its support functions
  145.  *      (in preporation for sourcing files)
  146.  *    - added Execute Buffer command
  147.  *    27-feb-86
  148.  *    - added execute(source) file command and added code to automatically
  149.  *      execute emacs.rc (or .emacsrc on UNIX) before initial read in
  150.  *    - changed version number to 3.4
  151.  *    4-mar-86
  152.  *    - changed word delete to be consistant with word move (it gets
  153.  *      rid of the inter word space now) This is configurable with the
  154.  *      NFWORD symbol in estruct.h
  155.  *    - added B_ACTIVE entry to the buffer table. Let emacs read multiple
  156.  *      file names from the command line and only read them in as needed
  157.  *    5-mar-85
  158.  *    - rewrote command line parser to get rid of my patchy code
  159.  *    - changed version number to 3.5
  160.  *    1-apr-86
  161.  *    - added support for Aztec C 3.20e under MSDOS
  162.  *    - fixed bug in mlwrite on ADM3's and thier ilk under V7
  163.  *    - added insertion of pounds in column one under CMODE
  164.  *    - changed version number to 3.6
  165.  *    3-apr-86
  166.  *    - added next-buffer command (^X-X)
  167.  *    5-apr-86
  168.  *    - added kill paragraph command (M-^W)
  169.  *    - changed fill-paragraph to leave 2 spaces after a period at the
  170.  *      end of a word.
  171.  *    - added OVERWRITE mode
  172.  *    7-apr-86
  173.  *    - fixed overwrite mode to handle tabs
  174.  *    8-apr-86
  175.  *    - added add/delete global mode (<ESC>M & <ESC> ^M) commands
  176.  *    9-apr-86
  177.  *    - added insert space command
  178.  *    - moved bindings around        ^C    insert space
  179.  *                    M-K    bind-to-key
  180.  *                    INSERT    insert space
  181.  *                    DELETE    forwdel
  182.  *    - added hunt forward and hunt reverse commands
  183.  *    10-apr-86
  184.  *    - fixed bug in DOBUF with non-terminated command string
  185.  *    15-apr-86
  186.  *    - fixed tab expansion bug in DISPLAY which hung the AMIGA
  187.  *      (send in by Dawn Banks)
  188.  *    - fixed curcol problen if forwline/backline during keyboard
  189.  *      macro execution (sent in by Ernst Christen)
  190.  *    - added AMIGA function/cursor key support
  191.  *    - fixed nonterminating <NL> replacement bug
  192.  *    - fixed word wrapping problems
  193.  *    16-apr-86
  194.  *    - updated documentation and froze development for 3.6 net release
  195.  *    23-apr-86    version 3.6a
  196.  *    - added forground and background colors. Setable with the
  197.  *      add mode commands for the moment
  198.  *    24-apr-86
  199.  *    - added command to pipe CLI output to a buffer
  200.  *    25-apr-86
  201.  *    - added Dana Hoggat's code to replace lattice's sick system()
  202.  *      function, now we no longer care what the switchar is.
  203.  *    - cleaned up the positioning on several of the spawing commands
  204.  *    26-apr-86
  205.  *    - added a output flush in vttidy(). Unix really appreciates this.
  206.  *    - added filter-buffer (^X#) command to send a buffer through
  207.  *      a dos filter
  208.  *    - made automatic CMODE on .c and .h file compilation dependant
  209.  *      in estruct.h
  210.  *    1-may-86
  211.  *    - optimized some code in update(). It certainly need a lot more.
  212.  *    - added AZTEC profiling capabilities. These are conditional on
  213.  *      the APROF symbol in estruct.h
  214.  *    2-may-86
  215.  *    - added (u)ndo command in query-replace. undoes last repalce.
  216.  *    6-may-86
  217.  *    - re-orginized and wrote the update() function in display.c
  218.  *      now my color hacks are in the right places and the code can be
  219.  *      understood.
  220.  *    [Released version 3.6f for BETA test sites]
  221.  *    8-may-86
  222.  *    - fixed bug in new display routine to wrap cursor on extended
  223.  *      lines at the right time
  224.  *    - modified the buffer-position command to give reasonable info
  225.  *    9-may-86
  226.  *    - improved the word wrap algorithm as not to discard non-space
  227.  *      delimiters. The backscan now looks for white space rather than
  228.  *      !inword().
  229.  *    [Released version 3.6g to Krannert]
  230.  *    10-may-86
  231.  *    - Added IBMPC.C an IBM-PC specific display driver. This makes paging
  232.  *      4-6 times faster. Also made some conditional changes to DISPLAY.C
  233.  *      to eliminate the pscreen[] if using the PC driver.
  234.  *    [changed version number to 3.6i]
  235.  *    12-may-86
  236.  *    - added delete-window (^X 0) command to dispose of a single window
  237.  *    - fixed problem with multiple prefixes from a command line which
  238.  *      was reported by John Gamble
  239.  *    14-may-86
  240.  *    - Added AZTEC support for the IBMPC display driver. Had to
  241.  *      readjust some includes and defines for this.
  242.  *    - fixed bug in delete-window.
  243.  *    - fixed some bizarre behavior with the cursor after coming back
  244.  *      from spawn calls.
  245.  *    [changed version number to 3.7 Freezing development for net release]
  246.  *    15-may-86
  247.  *    - (that didn't last long...) Added execute-macro-(1 thru 20) commands
  248.  *      to execute macro buffers (named "[Macro nn]")
  249.  *    - changed BFTEMP to BFINVS and cleaned up treatment of invisable
  250.  *      buffers.
  251.  *    16-may-86
  252.  *    - added store-macro (unbound) to store any executed command lines to
  253.  *      macro buffer.
  254.  *    - added clear-message-line (unbound) command to do just that
  255.  *    - added resize-window command to change a window's size to the
  256.  *      specified argument
  257.  *    - improved help's logic not to re-read the file if it was already
  258.  *      in a buffer
  259.  *    - added MAGIC mode to all structures and command tables, but the
  260.  *      regular expression code that John Gamble is writting is not ready.
  261.  *    18-may-86
  262.  *    - added interactive prompt requests in command line execution. IE
  263.  *      while executing a macro, a parameter starting with an at sign (@@)
  264.  *      causes emacs to prompt with the rest of the parameter and return
  265.  *      the resulting input as the value of the parameter.
  266.  *    - added arguments to split-current-window to force the cursor into
  267.  *      the upper or lower window.
  268.  *    20-may-86
  269.  *    - added support for the Microsoft C compiler as per the changes
  270.  *      send in by Oliver Sharp
  271.  *    - made some upgrades and fixes for VMS sent in by Guy Streeter
  272.  *    21-may-86
  273.  *    - fixed an AZTEC bug in ttgetc by clearing the upper byte
  274.  *    - fixed buf in CMODE with #preprocesser input (bug fix submitted by
  275.  *      Willis of unknown path)
  276.  *    - added support of alternative startup file ( @@<filename> ) in
  277.  *      the command line
  278.  *    - added ^Q quoting in interactive input (mlreplyt()).
  279.  *    - added re-binding of meta-prefix and ctlx-prefix
  280.  *    22-may-86
  281.  *    - reorginize getkey routines to make more sense and let prefix
  282.  *      binding work properly.
  283.  *    23-may-86
  284.  *    - checked new code on BSD4.2 made a few fixes
  285.  *    - added optional fence matching while in CMODE
  286.  *    - added goto and search command line arguments by Mike Spitzer
  287.  *    26-may-86
  288.  *    - added parameter fetching from buffers
  289.  *    27-may-86
  290.  *    - fixed some HP150 bugs......
  291.  *    31-may-86
  292.  *    - Added Wang PC keyboard support from modifications by
  293.  *      Sid Shapiro @@ Wang Institute
  294.  *    - Fixed some reverse video bugs with code submitted by Peter Chubb
  295.  *    - Fixed bug in nextbuffer reported by Dave Forslund
  296.  *    - added system V support (USG) from Linwood Varney
  297.  *    2-jun-86
  298.  *    - changed defines to just define one unix define (for example,
  299.  *      just define BSD for Unix BSD 4.2)
  300.  *    - Added Incremental search functions written by D. R. Banks
  301.  *      in file ISEARCH.C
  302.  *    - added insert-string (unbound) command to help the macro
  303.  *      language out.
  304.  *    - added unmark-buffer (M-~) command to turn off the current buffers
  305.  *      change flag
  306.  *    - fixed nxtarg to truncate strings longer than asked for max length
  307.  *    4-jun-86
  308.  *    - added special characters in command line tokens. Tidle (~) is
  309.  *      the special leadin character for "nrtb".
  310.  *    - Fixed bad ifdef in aztec code so it could look at HOME dir
  311.  *      for startup, help, and emacs.rc files
  312.  *    6-jun-86
  313.  *    - make delete word commands clear the kill buffer if not after another
  314.  *      kill command
  315.  *    11-jun-86
  316.  *    - made ~@@ in string arguments pass as char(192) to nxtarg() so one can
  317.  *      quote @@ at the beginning of string arguments
  318.  *    - changed buffer size vars in listbuffers() to long (for big files)
  319.  *    - re-wrote buffer-position command to be much faster
  320.  *    12-jun-86
  321.  *    - added count-words (M-^C) command to count the words/chars and
  322.  *      lines in a region
  323.  *    - changed regions so they could be larger than 65535 (short ->
  324.  *      long in the REGION structure)
  325.  *    - changed ldelete() and all callers to use a long size. The kill
  326.  *      buffer will still have a problem >65535 that can not be solved
  327.  *      until I restructure it.
  328.  *    - grouped paragraph commands and word count together under symbol
  329.  *      WORDPRO to allow them to be conditionally made (or not)
  330.  *    13-jun-86
  331.  *    - re-wrote kill buffer routines again. Now they support an unlimited
  332.  *      size kill buffer, and are (in theory) faster.
  333.  *    - changed delete-next-word (M-D) to not eat the newline after a word,
  334.  *      instead it checks and eats a newline at the cursor.
  335.  *    17-jun-85
  336.  *    - added numeric argument to next/previous-window to access the nth
  337.  *      window from the top/bottom
  338.  *    - added support for the data General 10 MSDOS machine
  339.  *    - added save-window (unbound) and restore-window (unbound) commands
  340.  *      for the use of the menu script. Save-window remembers which window
  341.  *      is current, and restore-window returns the cursor to that window.
  342.  *    20-jun-86
  343.  *    - fixed a bug with the fence matching locking up near the beginning
  344.  *    of a buffer
  345.  *    - added argument to update to selectivaly force a complete update
  346.  *    - added update-screen (unbound) command so macros can force a
  347.  *      screen update
  348.  *    21-jun-86
  349.  *    - rearranged token() and nxtarg() calls so that command names and
  350.  *      repeat counts could also be prompted and fetched from buffers
  351.  *      [this broke later with the exec re-write....]
  352.  *    - added write-message (unbound) command to write out a message
  353.  *      on the message line (for macros)
  354.  *    - changed ifdef's so that color modes are reconized as legal in
  355.  *      b/w version, and simply do nothing (allowing us to use the same
  356.  *      script files)
  357.  *    [Released version 3.7 on July 1 to the net and elswhere]
  358.  *    2-jul-86
  359.  *    - Changed search string terminator to always be the meta character
  360.  *      even if it is rebound.
  361.  *    3-jul-86
  362.  *    - removed extra calls to set color in startup code. This caused the
  363.  *      original current window always to be the global colors.
  364.  *    7-jul-86
  365.  *    - Fixed bugs in mlreplyt() so to work properly with all terminators
  366.  *      including control and spec characters
  367.  *    22-jul-86
  368.  *    - fixed replaces() so that it will return FALSE properly on the
  369.  *      input of the replacement string.
  370.  *    - added a definition for FAILED as a return type.....
  371.  *    - changed version number to 3.7b
  372.  *    23-jul-86
  373.  *    - fixed o -> 0 problem in termio.c
  374.  *    - made ^U universal-argument re-bindable
  375.  *    - wrote atoi() for systems (like aztec) where it acts screwy
  376.  *    - changed version number to 3.7c
  377.  *    25-jul-86
  378.  *    - make ^G abort-command rebindable
  379.  *    29-jul-86
  380.  *    - added HP110 Portable Computer support
  381.  *    - changed version number to 3.7d
  382.  *    30-jul-86
  383.  *    - Fixed a couple of errors in the new VMS code as pointer
  384.  *      out by Ken Shacklford
  385.  *    - split terminal open/close routines into screen and keyboard
  386.  *      open/close routines
  387.  *    - closed the keyboard during all disk I/O so that OS errors
  388.  *      can be respoded to correctly (especially on the HP150)
  389.  *    - changed version number to 3.7e
  390.  *    31-jul-86
  391.  *    - added label-function-key (unbound) command under symbol FLABEL
  392.  *      (primarily for the HP150)
  393.  *    4-aug-86
  394.  *    - added fixes for MicroSoft C as suggested by ihnp4!ihuxm!gmd1
  395.  *        <<remember to fix [list] deletion bug as reported
  396.  *          by craig@@hp-pcd>>
  397.  *    8-aug-86
  398.  *    - fixed beginning misspelling error everywhere
  399.  *    - fixed some more MSC errors
  400.  *    - changed version number to 3.7g
  401.  *    20-aug-86
  402.  *    - fixed CMODE .h scanning bug
  403.  *    - changed version number to 3.7h
  404.  *    30-aug-86
  405.  *    - fixed killing renamed [list] buffer (it can't) as submited
  406.  *      by James Aldridge
  407.  *    - Added code to allow multiple lines to display during
  408.  *      vertical retrace
  409.  *      [total disaster....yanked it back out]
  410.  *    9-sep-86
  411.  *    - added M-A (apropos) command to list commands containing a substring.
  412.  *    - fixed an inefficiency in the display update code submited
  413.  *      by William W. Carlson (wwc@@pur-ee)
  414.  *    10-sep-86
  415.  *    - added Dana Hoggatt's code for encryption and spliced it into the
  416.  *      proper commands. CRYPT mode now triggers encryption.
  417.  *    - added -k flag to allow encryption key (no spaces) in command line
  418.  *    14-sep-86
  419.  *    - added missing lastflag/thisflag processing to docmd()
  420.  *    - changed version to 3.7i and froze for partial release via mail
  421.  *      and BBS
  422.  *    05-oct-86
  423.  *    - changed some strcpys in main.c to strncpys as suggested by john
  424.  *      gamble
  425.  *    - replaces search.c and isearch.c with versions modified by
  426.  *      john gamble
  427.  *    10-oct-86
  428.  *    - removed references to lflick....it just won't work that way.
  429.  *    - removed defines LAT2 and LAT3...the code no longer is lattice
  430.  *      version dependant.
  431.  *    14-oct-86
  432.  *    - changed spawn so that it will not not pause if executed from
  433.  *      a command line
  434.  *    15-oct-86
  435.  *    - added argument concatination (+) to the macro parsing
  436.  *    - added [] as fence pairs
  437.  *    16-oct-86
  438.  *    - rewrote all macro line parsing routines and rearranged the
  439.  *      mlreply code. saved .6K!!! and have blazed the path for expanding
  440.  *      the command language.
  441.  *    17-oct-86
  442.  *    - added new keyboard macro routines (plus a new level to the
  443.  *      input character function)
  444.  *    22-oct-86
  445.  *    - improved EGA cursor problems
  446.  *    - added -r (restricted) switch to command line for BBS use
  447.  *    06-nov-86
  448.  *    - fixed terminator declarations from char to int in getarg() and
  449.  *      nxtarg() in exec.c as pointed out by john gamble
  450.  *    07-nov-86
  451.  *    - made wordrap() user callable as wrap-word (M-FNW) and changed
  452.  *      the getckey() routine so that illegal keystrokes (too many
  453.  *      prefixes set) could be used for internal bindings. When word
  454.  *      wrap conditions are met, the keystroke M-FNW is executed. Added
  455.  *      word wrap check/call to newline().
  456.  *    11-nov-86
  457.  *    - added and checked support for Mark Williams C 86
  458.  *    12-nov-86
  459.  *    - added goto-matching-fence (M-^F) command to jump to a matching
  460.  *      fence "({[]})" or beep if there is none. This can reframe the
  461.  *      screen.
  462.  *    - added code and structure elements to support change-screen-size
  463.  *      command (M-^S) to change the number of lines being used by
  464.  *      MicroEMACS.
  465.  *    15-nov-86
  466.  *    - finished debuging change-screen-size
  467.  *    17-nov-86
  468.  *    - Encorporated in James Turner's modifications for the Atari ST
  469.  *        23-sep-86
  470.  *        - added support for the Atari ST line of computers (jmt)
  471.  *        --added a '\r' to the end of each line on output and strip
  472.  *          it on input for the SHOW function from the desktop
  473.  *        --added 3 new mode functions (HIREZ, MEDREZ, and LOREZ); chgrez
  474.  *          routine in TERM structure; and MULTREZ define in estructs.h
  475.  *          to handle multiple screen resolutions
  476.  *    [note....ST still not running under lattice yet...]
  477.  *    25-nov-86
  478.  *    - Made the filter-buffer (^X-#) command not work on VIEW mode
  479.  *      buffers
  480.  *    - Made the quick-exit (M-Z) command throw out a newline after 
  481.  *      each message so they could be seen.
  482.  *    26-nov-86
  483.  *    - fixed a couple of bugs in change-screen-size (M-^S) command
  484.  *    - changed file read behavior on long lines and last lines
  485.  *      with no newline (it no longer throws the partial line out)
  486.  *    - [as suggested by Dave Tweten] Made adding a ^Z to the end
  487.  *      of an output file under MSDOS configurable under the
  488.  *      CTRLZ symbol in estruct.h
  489.  *    - [Dave Tweten] Spawn will look up the "TMP" environment variable
  490.  *      for use during various pipeing commands.
  491.  *    - [Dave Tweten] changed pipe command under MSDOS to use '>>'
  492.  *      instead of '>'
  493.  *    04-dec-86
  494.  *    - moved processing of '@@' and '#' so that they can be outside
  495.  *      the quotes in an argument, and added hooks to process '%' for
  496.  *      environment and user variables.
  497.  *    - modified ibmpc.c to sence the graphics adapter (CGA and MONO)
  498.  *      at runtime to cut down on the number of versions.
  499.  *    05-dec-86
  500.  *    - changed macro directive character to "!" instead of "$" (see
  501.  *      below) and fixed the standard .rc file to comply.
  502.  *    - added code to interpret environment variables ($vars). Added
  503.  *      hooks for built in functions (&func). So, to recap:
  504.  *
  505.  *        @@<string>    prompt and return a string from the user
  506.  *        #<buffer name>    get the next line from a buffer and advance
  507.  *        %<var>        get user variable <var>
  508.  *        $<evar>        get environment variable <evar>
  509.  *        &<func>        evaluate function <func>
  510.  *
  511.  *    - allowed repeat counts to be any of the above
  512.  *    - added code to allow insert-string (unbound) to use its
  513.  *      repeat count properly
  514.  *    - added set (^X-A) command to set variables. Only works on
  515.  *      environmental vars yet.
  516.  *    9-dec-86
  517.  *    - added some code for user defined variables...more to come
  518.  *    - added options for malloc() memory pool tracking
  519.  *    - preliminary user variables (%) working
  520.  *    - changed terminal calls to macro's (to prepare for the new
  521.  *      terminal drivers)
  522.  *    15-dec-86
  523.  *    - changed previous-line (^P) and next-line (^N) to return a
  524.  *      FALSE at the end or beginning of the file so repeated
  525.  *      macros involving them terminate properly!
  526.  *    - added code for $CURCOL and $CURLINE
  527.  *    20-dec-86
  528.  *    - set (^X-A) now works with all vars
  529.  *    - added some new functions
  530.  *          &ADD &SUB &TIMES &DIV &MOD &NEG &CAT
  531.  *    - yet again rearranged functions to control macro execution. Did
  532.  *      away with getarg()
  533.  *    23-dec-86
  534.  *    - added string functions
  535.  *          &LEFt &RIGht &MID
  536.  *    31-dec-86
  537.  *    - added many logical functions
  538.  *          &NOT &EQUal &LESs &GREater
  539.  *    - added string functions
  540.  *          &SEQual &SLEss &SGReater
  541.  *    - added variable indirection with &INDirect
  542.  *    - made fixes to allow recursive macro executions
  543.  *      (improved speed during macro execution as well)
  544.  *    3-jan-87
  545.  *    - added $FLICKER to control flicker supression
  546.  *    - made spawn commands restricted
  547.  *    - cleaned up lots of unintentional int<->char problems
  548.  *    4-jan-87
  549.  *    - Fixed broken pipe-command (^X-@@) command under MSDOS
  550.  *    - added !IF  !ELSE  !ENDIF  directives and changed the
  551.  *      name of !END to !ENDM....real slick stuff
  552.  *    5-jan-87
  553.  *    - quick-exit (M-Z) aborts on any filewrite errors
  554.  *    8-jan-87
  555.  *    - debugged a lot of the new directive and evaluation code.
  556.  *      BEWARE of stack space overflows! (increasing stack to
  557.  *      16K under MSDOS)
  558.  *    - removed non-standard DEC Rainbow keyboard support...let someone
  559.  *      PLEASE impliment this in the standard manner using key bindings
  560.  *      and send the results to me.
  561.  *    - added change-screen-width () command and $CURWIDTH variable
  562.  *    11-jan-87
  563.  *    - fixed an increadably deeply buried bug in vtputc and combined
  564.  *      it with vtpute (saving about 200 bytes!)
  565.  *    16-jan-87
  566.  *    - added code to handle controling multiple screen resolutions...
  567.  *      allowed the IBM-PC driver to force mono or cga modes.
  568.  *    - added current buffer name and filename variables
  569.  *      $cbufname and $cfname
  570.  *    18-jan-87
  571.  *    - added $sres variable to control screen resolution
  572.  *    - added $debug variable to control macro debugging code (no longer
  573.  *      is this activated by GLOBAL spell mode)
  574.  *    - fixed bug in -g command line option
  575.  *    - Released Version 3.8 to BBSNET
  576.  *    21-jan-87
  577.  *    - added $status variable to record return status of last command
  578.  */
  579.  
  580. #include        <stdio.h>
  581.  
  582. /* for MSDOS, increase the default stack space */
  583.  
  584. #if    MSDOS & LATTICE
  585. unsigned _stack = 16536;
  586. #endif
  587.  
  588. #if    MSDOS & AZTEC
  589. int _STKSIZ = 16536/16;        /* stack size in paragraphs */
  590. int _STKRED = 1024;        /* stack checking limit */
  591. int _HEAPSIZ = 4096/16;        /* (in paragraphs) */
  592. int _STKLOW = 0;        /* default is stack above heap (small only) */
  593. #endif
  594.  
  595. /* make global definitions not external */
  596. #define    maindef
  597.  
  598. #include        "estruct.h"    /* global structures and defines */
  599. #include    "efunc.h"    /* function declarations and name table    */
  600. #include    "edef.h"    /* global definitions */
  601. #include    "ebind.h"    /* default key bindings */
  602.  
  603. #if    MEGAMAX
  604. overlay "main"
  605. #endif
  606.  
  607. #if     VMS
  608. #include        <ssdef.h>
  609. #define GOOD    (SS$_NORMAL)
  610. #endif
  611.  
  612. #ifndef GOOD
  613. #define GOOD    0
  614. #endif
  615.  
  616. #if    APROF    /* Declarations needed for AZTEC C profiling */
  617. int _Corg();    /* first address of program */
  618. int _Cend();    /* last address of program */
  619.  
  620. short monbuf[NBUCK];    /* buffer for gather info */
  621. #endif
  622.  
  623. main(argc, argv)
  624. char    *argv[];
  625. {
  626.         register int    c;
  627.         register int    f;
  628.         register int    n;
  629.         register int    mflag;
  630.     register BUFFER *bp;
  631.     register int    ffile;        /* first file flag */
  632.     register int    carg;        /* current arg to scan */
  633.     register int    startf;        /* startup executed flag */
  634.     int basec;            /* c stripped of meta character */
  635.     int viewflag;            /* are we starting in view mode? */
  636.         int gotoflag;                   /* do we need to goto a line at start? */
  637.         int gline;                      /* if so, what line? */
  638.         int searchflag;                 /* Do we need to search at start? */
  639.         char bname[NBUFN];        /* buffer name of file to read */
  640. #if    CRYPT
  641.     int eflag;            /* encrypting on the way in? */
  642.     char ekey[NPAT];        /* startup encryption key */
  643. #endif
  644.  
  645. #if    APROF
  646.     /* if we are doing AZTEC C profiling, start it up */
  647.     /*_intr_sp(18);     set clock interupt for 60/second */
  648.     monitor(_Corg, _Cend, monbuf, NBUCK, 0);
  649. #endif
  650.  
  651.     /* initialize the editor and process the command line arguments */
  652.         strcpy(bname, "main");    /* default buffer name */
  653.         vtinit();        /* Displays.            */
  654.         edinit(bname);        /* Buffers, windows.    */
  655.     varinit();        /* user variables */
  656.     viewflag = FALSE;    /* view mode defaults off in command line */
  657.     gotoflag = FALSE;    /* set to off to begin with */
  658.     searchflag = FALSE;    /* set to off to begin with */
  659.     ffile = TRUE;        /* no file to edit yet */
  660.     startf = FALSE;        /* startup file not executed yet */
  661. #if    CRYPT
  662.     eflag = FALSE;        /* no encryption by default */
  663. #endif
  664. #if    COLOR
  665.     curwp->w_fcolor = gfcolor;        /* and set colors    */
  666.     curwp->w_bcolor = gbcolor;
  667. #endif
  668.     
  669.     /* scan through the command line and get the files to edit */
  670.     for (carg = 1; carg < argc; ++carg) {
  671.         /* if its a switch, process it */
  672.         if (argv[carg][0] == '-') {
  673.             switch (argv[carg][1]) {
  674.                 case 'v':    /* -v for View File */
  675.                 case 'V':
  676.                     viewflag = TRUE;
  677.                     break;
  678.                 case 'e':    /* -e for Edit file */
  679.                 case 'E':
  680.                     viewflag = FALSE;
  681.                     break;
  682.                 case 's':    /* -s for initial search string */
  683.                 case 'S':
  684.                     searchflag = TRUE;
  685.                     strncpy(pat,&argv[carg][2],NPAT);
  686.                     break;
  687.                 case 'g':    /* -g for initial goto */
  688.                 case 'G':    
  689.                     gotoflag = TRUE;
  690.                     gline = atoi(&argv[carg][2]);
  691.                     break;
  692.                 case 'r':    /* -r restrictive use */
  693.                 case 'R':
  694.                     restflag = TRUE;
  695.                     break;
  696. #if    CRYPT
  697.                 case 'k':    /* -k<key> for code key */
  698.                 case 'K':
  699.                     if (argv[carg][2] == 0)
  700.                         eflag = FALSE;
  701.                     else {
  702.                         eflag = TRUE;
  703.                         strcpy(ekey, &argv[carg][2]);
  704.                     }
  705.                     break;
  706. #endif
  707.                 default:    /* unknown switch */
  708.                     /* ignore this for now */
  709.                     break;
  710.             }
  711.         } else     /* check for a macro file */
  712.             if (argv[carg][0]== '@@') {
  713.  
  714.             if (startup(&argv[carg][1]) == TRUE)
  715.                 startf = TRUE;    /* don't execute emacs.rc */
  716.  
  717.         } else {    /* process a file name */
  718.             /* if we haven't run emacs.rc, do it now */
  719.             if (startf == FALSE) {
  720.                 startup("");
  721.                 startf = TRUE;
  722. #if    COLOR
  723.                 curwp->w_fcolor = gfcolor;
  724.                 curwp->w_bcolor = gbcolor;
  725. #endif
  726.             }
  727.  
  728.             /* set up a buffer for this file */
  729.                     makename(bname, argv[carg]);
  730.  
  731. #if    CRYPT
  732.             /* set up for de-cryption if needed */
  733.             if (eflag) {
  734.                 curbp->b_mode |= MDCRYPT;
  735.                 strncpy(curbp->b_key, ekey, NPAT);
  736.                 crypt((char *)NULL, 0);
  737.                 crypt(curbp->b_key, strlen(curbp->b_key));
  738.             }
  739. #endif
  740.  
  741.             /* if this is the first file, read it in */
  742.             if (ffile) {
  743.                 bp = curbp;
  744.                 makename(bname, argv[carg]);
  745.                 strcpy(bp->b_bname, bname);
  746.                 strcpy(bp->b_fname, argv[carg]);
  747.                 if (readin(argv[carg], (viewflag==FALSE))
  748.                                 == ABORT) {
  749.                     strcpy(bp->b_bname, "main");
  750.                     strcpy(bp->b_fname, "");
  751.                 }
  752.                 bp->b_dotp = bp->b_linep;
  753.                 bp->b_doto = 0;
  754.                 ffile = FALSE;
  755.             } else {
  756.                 /* set this to inactive */
  757.                 bp = bfind(bname, TRUE, 0);
  758.                 strcpy(bp->b_fname, argv[carg]);
  759.                 bp->b_active = FALSE;
  760.             }
  761.  
  762.             /* set the view mode appropriatly */
  763.             if (viewflag)
  764.                 bp->b_mode |= MDVIEW;
  765.         }
  766.     }
  767.  
  768.     /* if invoked with nothing, run the startup file here */
  769.     if (startf == FALSE) {
  770.         startup("");
  771.         startf = TRUE;
  772. #if    COLOR
  773.         curwp->w_fcolor = gfcolor;
  774.         curwp->w_bcolor = gbcolor;
  775. #endif
  776.     }
  777.  
  778.         /* Deal with startup gotos and searches */
  779.  
  780.         if (gotoflag && searchflag) {
  781.             update(FALSE);
  782.         mlwrite("[Can not search and goto at the same time!]");
  783.     }
  784.         else if (gotoflag) {
  785.                 if (gotoline(TRUE,gline) == FALSE) {
  786.                     update(FALSE);
  787.             mlwrite("[Bogus goto argument]");
  788.         }
  789.         } else if (searchflag) {
  790.                 if (forwhunt(FALSE, 0) == FALSE)
  791.                     update(FALSE);
  792.         }
  793.  
  794.     /* setup to process commands */
  795.         lastflag = 0;                           /* Fake last flags.     */
  796.     curbp->b_mode |= gmode;            /* and set default modes*/
  797.     curwp->w_flag |= WFMODE;        /* and force an update    */
  798.  
  799. loop:
  800.         update(FALSE);                          /* Fix up the screen    */
  801.         c = getcmd();
  802.         if (mpresf != FALSE) {
  803.                 mlerase();
  804.                 update(FALSE);
  805. #if    CLRMSG
  806.                 if (c == ' ')                   /* ITS EMACS does this  */
  807.                         goto loop;
  808. #endif
  809.         }
  810.         f = FALSE;
  811.         n = 1;
  812.  
  813.     /* do META-# processing if needed */
  814.  
  815.     basec = c & ~META;        /* strip meta char off if there */
  816.     if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
  817.         f = TRUE;        /* there is a # arg */
  818.         n = 0;            /* start with a zero default */
  819.         mflag = 1;        /* current minus flag */
  820.         c = basec;        /* strip the META */
  821.         while ((c >= '0' && c <= '9') || (c == '-')) {
  822.             if (c == '-') {
  823.                 /* already hit a minus or digit? */
  824.                 if ((mflag == -1) || (n != 0))
  825.                     break;
  826.                 mflag = -1;
  827.             } else {
  828.                 n = n * 10 + (c - '0');
  829.             }
  830.             if ((n == 0) && (mflag == -1))    /* lonely - */
  831.                 mlwrite("Arg:");
  832.             else
  833.                 mlwrite("Arg: %d",n * mflag);
  834.  
  835.             c = getcmd();    /* get the next key */
  836.         }
  837.         n = n * mflag;    /* figure in the sign */
  838.     }
  839.  
  840.     /* do ^U repeat argument processing */
  841.  
  842.         if (c == reptc) {                  /* ^U, start argument   */
  843.                 f = TRUE;
  844.                 n = 4;                          /* with argument of 4 */
  845.                 mflag = 0;                      /* that can be discarded. */
  846.                 mlwrite("Arg: 4");
  847.                 while ((c=getcmd()) >='0' && c<='9' || c==reptc || c=='-'){
  848.                         if (c == reptc)
  849.                 if ((n > 0) == ((n*4) > 0))
  850.                                     n = n*4;
  851.                             else
  852.                                 n = 1;
  853.                         /*
  854.                          * If dash, and start of argument string, set arg.
  855.                          * to -1.  Otherwise, insert it.
  856.                          */
  857.                         else if (c == '-') {
  858.                                 if (mflag)
  859.                                         break;
  860.                                 n = 0;
  861.                                 mflag = -1;
  862.                         }
  863.                         /*
  864.                          * If first digit entered, replace previous argument
  865.                          * with digit and set sign.  Otherwise, append to arg.
  866.                          */
  867.                         else {
  868.                                 if (!mflag) {
  869.                                         n = 0;
  870.                                         mflag = 1;
  871.                                 }
  872.                                 n = 10*n + c - '0';
  873.                         }
  874.                         mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1));
  875.                 }
  876.                 /*
  877.                  * Make arguments preceded by a minus sign negative and change
  878.                  * the special argument "^U -" to an effective "^U -1".
  879.                  */
  880.                 if (mflag == -1) {
  881.                         if (n == 0)
  882.                                 n++;
  883.                         n = -n;
  884.                 }
  885.         }
  886.  
  887.     /* and execute the command */
  888.         execute(c, f, n);
  889.         goto loop;
  890. }
  891.  
  892. /*
  893.  * Initialize all of the buffers and windows. The buffer name is passed down
  894.  * as an argument, because the main routine may have been told to read in a
  895.  * file by default, and we want the buffer name to be right.
  896.  */
  897. edinit(bname)
  898. char    bname[];
  899. {
  900.         register BUFFER *bp;
  901.         register WINDOW *wp;
  902.     char *malloc();
  903.  
  904.         bp = bfind(bname, TRUE, 0);             /* First buffer         */
  905.         blistp = bfind("[List]", TRUE, BFINVS); /* Buffer list buffer   */
  906.         wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window         */
  907.         if (bp==NULL || wp==NULL || blistp==NULL)
  908.                 exit(1);
  909.         curbp  = bp;                            /* Make this current    */
  910.         wheadp = wp;
  911.         curwp  = wp;
  912.         wp->w_wndp  = NULL;                     /* Initialize window    */
  913.         wp->w_bufp  = bp;
  914.         bp->b_nwnd  = 1;                        /* Displayed.           */
  915.         wp->w_linep = bp->b_linep;
  916.         wp->w_dotp  = bp->b_linep;
  917.         wp->w_doto  = 0;
  918.         wp->w_markp = NULL;
  919.         wp->w_marko = 0;
  920.         wp->w_toprow = 0;
  921. #if    COLOR
  922.     /* initalize colors to global defaults */
  923.     wp->w_fcolor = gfcolor;
  924.     wp->w_bcolor = gbcolor;
  925. #endif
  926.         wp->w_ntrows = term.t_nrow-1;           /* "-1" for mode line.  */
  927.         wp->w_force = 0;
  928.         wp->w_flag  = WFMODE|WFHARD;            /* Full.                */
  929. }
  930.  
  931. /*
  932.  * This is the general command execution routine. It handles the fake binding
  933.  * of all the keys to "self-insert". It also clears out the "thisflag" word,
  934.  * and arranges to move it to the "lastflag", so that the next command can
  935.  * look at it. Return the status of command.
  936.  */
  937. execute(c, f, n)
  938. {
  939.         register KEYTAB *ktp;
  940.         register int    status;
  941.  
  942.         ktp = &keytab[0];                       /* Look in key table.   */
  943.         while (ktp->k_fp != NULL) {
  944.                 if (ktp->k_code == c) {
  945.                         thisflag = 0;
  946.                         status   = (*ktp->k_fp)(f, n);
  947.                         lastflag = thisflag;
  948.                         return (status);
  949.                 }
  950.                 ++ktp;
  951.         }
  952.  
  953.         /*
  954.          * If a space was typed, fill column is defined, the argument is non-
  955.          * negative, wrap mode is enabled, and we are now past fill column,
  956.      * and we are not read-only, perform word wrap.
  957.          */
  958.         if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 &&
  959.         n >= 0 && getccol(FALSE) > fillcol &&
  960.         (curwp->w_bufp->b_mode & MDVIEW) == FALSE)
  961.         execute(META|SPEC|'W', FALSE, 1);
  962.  
  963.         if ((c>=0x20 && c<=0x7E)                /* Self inserting.      */
  964.         ||  (c>=0xA0 && c<=0xFE)) {
  965.                 if (n <= 0) {                   /* Fenceposts.          */
  966.                         lastflag = 0;
  967.                         return (n<0 ? FALSE : TRUE);
  968.                 }
  969.                 thisflag = 0;                   /* For the future.      */
  970.  
  971.         /* if we are in overwrite mode, not at eol,
  972.            and next char is not a tab or we are at a tab stop,
  973.            delete a char forword            */
  974.         if (curwp->w_bufp->b_mode & MDOVER &&
  975.             curwp->w_doto < curwp->w_dotp->l_used &&
  976.             (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
  977.              (curwp->w_doto) % 8 == 7))
  978.                 ldelete(1L, FALSE);
  979.  
  980.         /* do the appropriate insertion */
  981.         if (c == '}' && (curbp->b_mode & MDCMOD) != 0)
  982.                 status = insbrace(n, c);
  983.             else if (c == '#' && (curbp->b_mode & MDCMOD) != 0)
  984.                 status = inspound();
  985.             else
  986.                     status = linsert(n, c);
  987.  
  988. #if    CFENCE
  989.         /* check for CMODE fence matching */
  990.         if ((c == '}' || c == ')' || c == ']') &&
  991.                 (curbp->b_mode & MDCMOD) != 0)
  992.             fmatch(c);
  993. #endif
  994.  
  995.                 lastflag = thisflag;
  996.                 return (status);
  997.         }
  998.     TTbeep();
  999.     mlwrite("[Key not bound]");        /* complain        */
  1000.         lastflag = 0;                           /* Fake last flags.     */
  1001.         return (FALSE);
  1002. }
  1003.  
  1004. /*
  1005.  * Fancy quit command, as implemented by Norm. If the any buffer has
  1006.  * changed do a write on that buffer and exit emacs, otherwise simply exit.
  1007.  */
  1008. quickexit(f, n)
  1009. {
  1010.     register BUFFER *bp;    /* scanning pointer to buffers */
  1011.     register int status;
  1012.  
  1013.     bp = bheadp;
  1014.     while (bp != NULL) {
  1015.             if ((bp->b_flag&BFCHG) != 0    /* Changed.             */
  1016.             && (bp->b_flag&BFINVS) == 0) {    /* Real.                */
  1017.             curbp = bp;        /* make that buffer cur    */
  1018.             mlwrite("[Saving %s]\n",bp->b_fname);
  1019.                     if ((status = filesave(f, n)) != TRUE)
  1020.                         return(status);
  1021.         }
  1022.     bp = bp->b_bufp;            /* on to the next buffer */
  1023.     }
  1024.         quit(f, n);                             /* conditionally quit   */
  1025. }
  1026.  
  1027. /*
  1028.  * Quit command. If an argument, always quit. Otherwise confirm if a buffer
  1029.  * has been changed and not written out. Normally bound to "C-X C-C".
  1030.  */
  1031. quit(f, n)
  1032. {
  1033.         register int    s;
  1034.  
  1035.         if (f != FALSE                          /* Argument forces it.  */
  1036.         || anycb() == FALSE                     /* All buffers clean.   */
  1037.                         /* User says it's OK.   */
  1038.         || (s=mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
  1039. #if    FILOCK
  1040.         if (lockrel() != TRUE) {
  1041.             TTputc('\n');
  1042.             TTputc('\r');
  1043.             TTclose();
  1044.             TTkclose();
  1045.             exit(1);
  1046.         }
  1047. #endif
  1048.                 vttidy();
  1049. #if    APROF
  1050.         /* if doing AZTEC C profiling, close up and write it out */
  1051.         monitor(0,0,0,0,0);
  1052. #endif
  1053.                 exit(GOOD);
  1054.         }
  1055.     mlwrite("");
  1056.         return (s);
  1057. }
  1058.  
  1059. /*
  1060.  * Begin a keyboard macro.
  1061.  * Error if not at the top level in keyboard processing. Set up variables and
  1062.  * return.
  1063.  */
  1064. ctlxlp(f, n)
  1065. {
  1066.         if (kbdmode != STOP) {
  1067.                 mlwrite("%%Macro already active");
  1068.                 return(FALSE);
  1069.         }
  1070.         mlwrite("[Start macro]");
  1071.     kbdptr = &kbdm[0];
  1072.     kbdend = kbdptr;
  1073.         kbdmode = RECORD;
  1074.         return (TRUE);
  1075. }
  1076.  
  1077. /*
  1078.  * End keyboard macro. Check for the same limit conditions as the above
  1079.  * routine. Set up the variables and return to the caller.
  1080.  */
  1081. ctlxrp(f, n)
  1082. {
  1083.         if (kbdmode == STOP) {
  1084.                 mlwrite("%%Macro not active");
  1085.                 return(FALSE);
  1086.         }
  1087.     if (kbdmode == RECORD) {
  1088.             mlwrite("[End macro]");
  1089.             kbdmode = STOP;
  1090.     }
  1091.         return(TRUE);
  1092. }
  1093.  
  1094. /*
  1095.  * Execute a macro.
  1096.  * The command argument is the number of times to loop. Quit as soon as a
  1097.  * command gets an error. Return TRUE if all ok, else FALSE.
  1098.  */
  1099. ctlxe(f, n)
  1100. {
  1101.         if (kbdmode != STOP) {
  1102.                 mlwrite("%%Macro already active");
  1103.                 return(FALSE);
  1104.         }
  1105.         if (n <= 0)
  1106.                 return (TRUE);
  1107.     kbdrep = n;        /* remember how many times to execute */
  1108.     kbdmode = PLAY;        /* start us in play mode */
  1109.     kbdptr = &kbdm[0];    /*    at the beginning */
  1110.     return(TRUE);
  1111. }
  1112.  
  1113. /*
  1114.  * Abort.
  1115.  * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
  1116.  * Sometimes called as a routine, to do general aborting of stuff.
  1117.  */
  1118. ctrlg(f, n)
  1119. {
  1120.         TTbeep();
  1121.     kbdmode = STOP;
  1122.     mlwrite("[Aborted]");
  1123.         return(ABORT);
  1124. }
  1125.  
  1126. /* tell the user that this command is illegal while we are in
  1127.    VIEW (read-only) mode                */
  1128.  
  1129. rdonly()
  1130.  
  1131. {
  1132.     TTbeep();
  1133.     mlwrite("[Key illegal in VIEW mode]");
  1134.     return(FALSE);
  1135. }
  1136.  
  1137. resterr()
  1138.  
  1139. {
  1140.     TTbeep();
  1141.     mlwrite("[That command is RESTRICTED]");
  1142.     return(FALSE);
  1143. }
  1144.  
  1145. meta()    /* dummy function for binding to meta prefix */
  1146. {
  1147. }
  1148.  
  1149. cex()    /* dummy function for binding to control-x prefix */
  1150. {
  1151. }
  1152.  
  1153. unarg()    /* dummy function for binding to universal-argument */
  1154. {
  1155. }
  1156.  
  1157. /*****        Compiler specific Library functions    ****/
  1158.  
  1159. #if    MWC86 & MSDOS
  1160. movmem(source, dest, size)
  1161.  
  1162. char *source;    /* mem location to move memory from */
  1163. char *dest;    /* memory location to move text to */
  1164. int size;    /* number of bytes to move */
  1165.  
  1166. {
  1167.     register int i;
  1168.  
  1169.     for (i=0; i < size; i++)
  1170.         *dest++ = *source++;
  1171. }
  1172. #endif
  1173.  
  1174. #if    RAMSIZE & LATTICE & MSDOS
  1175. /*    These routines will allow me to track memory usage by placing
  1176.     a layer on top of the standard system malloc() and free() calls.
  1177.     with this code defined, the environment variable, $RAM, will
  1178.     report on the number of bytes allocated via malloc.
  1179.  
  1180.     with SHOWRAM defined, the number is also posted on the
  1181.     end of the bottom mode line and is updated whenever it is changed.
  1182. */
  1183.  
  1184. #undef    malloc
  1185. #undef    free
  1186.  
  1187. char *allocate(nbytes)    /* allocate nbytes and track */
  1188.  
  1189. unsigned nbytes;    /* # of bytes to allocate */
  1190.  
  1191. {
  1192.     char *mp;    /* ptr returned from malloc */
  1193.     char *malloc();
  1194.  
  1195.     mp = malloc(nbytes);
  1196.     if (mp) {
  1197.         envram += nbytes;
  1198. #if    RAMSHOW
  1199.         dspram();
  1200. #endif
  1201.     }
  1202.  
  1203.     return(mp);
  1204. }
  1205.  
  1206. release(mp)    /* release malloced memory and track */
  1207.  
  1208. char *mp;    /* chunk of RAM to release */
  1209.  
  1210. {
  1211.     unsigned *lp;    /* ptr to the long containing the block size */
  1212.  
  1213.     if (mp) {
  1214.         lp = ((unsigned *)mp) - 1;
  1215.  
  1216.         /* update amount of ram currently malloced */
  1217.         envram -= (long)*lp - 2;
  1218.         free(mp);
  1219. #if    RAMSHOW
  1220.         dspram();
  1221. #endif
  1222.     }
  1223. }
  1224.  
  1225. #if    RAMSHOW
  1226. dspram()    /* display the amount of RAM currently malloced */
  1227.  
  1228. {
  1229.     char mbuf[20];
  1230.     char *sp;
  1231.  
  1232.     TTmove(term.t_nrow - 1, 70);
  1233. #if    COLOR
  1234.     TTforg(7);
  1235.     TTbacg(0);
  1236. #endif
  1237.     sprintf(mbuf, "[%lu]", envram);
  1238.     sp = &mbuf[0];
  1239.     while (*sp)
  1240.         TTputc(*sp++);
  1241.     TTmove(term.t_nrow, 0);
  1242.     movecursor(term.t_nrow, 0);
  1243. }
  1244. #endif
  1245. #endif
  1246.  
  1247. @
  1248.